Wir wollen unseren Anwendungen ein Schlafen ermöglichen, also ein zeitgesteuertes Warten.
Das soll durch die Funktion sleep realisiert werden, welche Ähnlichkeiten mit dem gleichnamigen
posX Gegenstück hat, aber bei uns die Zeitangaben in Millisekunden haben will.
Wenn sich ein Pfaden schlafen legt, soll er analog zu den blockierten Threads beim wechselseitigen
Ausschluss aus der Bereitschaftsliste entnommen und in ein Warte- bzw. Schlafzimmer überführt
werden, zu welchem noch eine Schlafenszeit anodiert wird, im Beispiel 13 Millisekunden.
Für dieses Video werde ich dafür von nun an diese kompaktere, aber äquivalente Darstellung
für zeitbasierte Wartezimmer verwenden.
Die Schlafenszeit wird jede Millisekunde um 1 verringert, bis sie die Null erreicht und
damit abgelaufen ist.
Wir wecken den Faden wieder auf, indem wir ihn wieder in die Bereitschaftsliste einreihen.
So weit, so einfach.
Aber wie verwalten wir am besten die schlafenden Anwendungsfäden?
Als Beispiel legen wir 3 Struts schlafen.
Foo für 666 Millisekunden, Bar für 23 Millisekunden und Buds für 42 Millisekunden.
Der einfachste Weg ist natürlich, diese Wartezimmer mittels verketteter Liste zu verwalten.
Das hat aber die Nachteil, dass bei jedem Tick die ganze Liste durchlaufen werden muss.
Die Komplexität beträgt nach der Landau-Notation O von N, also jeder der N-Einträge muss bei
jedem Tick geändert werden und das durch unsere Taktung eben 1000 Mal pro Sekunde bei
der Bearbeitung der Timerunterbrechung in der Epilog-Ibene.
Kann also bei vielen schlafenden Fäden schnell hässlich werden.
Das muss doch besser gehen.
Wie wäre es denn mit einer absoluten Zeit, welche mit jedem Tick um 1 hochzählt?
Wenn sich am Faden schlafen liegt, berechnen wir mit Hilfe der aktuellen Zeit die Aufwachzeit.
Soweit haben wir von der Komplexität natürlich noch nichts gewonnen, es sei denn wir verwenden
zusätzlich eine Priority-Q.
Dort kostet uns das Einordnen O von N, da wir die Schlange durchgehen müssen, um den
Platz zu finden.
Aber das Prüfen bei jedem Tick, ob der erste Eintrag der aktuellen Zeit entspricht, ist
in der Regel dann ein konstanter Aufwand O von 1.
Um das durchzuführen, müssen wir mit der absoluten Zeit einen neuen Zustand einführen.
Und sollte natürlich 32bit vermeiden, da hier ein Überlauf bereits nach knapp 50
Tagen auftritt.
Das schöne an der Lösung ist, dass wir nur das erste Element in der Schlange anfassen
müssen.
Können wir daraus nicht etwas stricken, was ohne die absolute Zeit auskommt?
Zum Beispiel können wir doch eine relative Delta-Zeit verwenden, also jeweils nur die
Zeitdifferenz zum vorherigen Eintrag in der Schlange uns merken.
Und dabei natürlich keine negativen Differenzen zulassen, nur positive oder Null.
Zur Veranschauliche nehmen wir wieder das vorherige Beispiel.
Phu will sich für 666ms schlafen legen.
Bis jetzt ist die Liste leer, aber implizit muss natürlich definiert sein, dass der Vorgänger
des ersten Elements die Zeit t0 mit 0ms hat.
Somit beträgt die Zeitdifferenz auf das erste Element 666ms, wenn wir es einhängen.
Der zweite Threadbar möchte sich nur 23ms schlafen legen.
Dazu muss er von vorne beginnend an die richtige Stelle eingeordnet werden.
Zuerst prüfen wir wieder gegen t0 die Zeitdifferenz, diese beträgt mit 23ms weniger als das derzeitige
erste Element.
Wir hängen es also an den Anfang der Liste.
Für Phu waren noch 666 verbleibende Millisekunden im Vergleich zu t0 eingetragen, aber da wir
Presenters
Zugänglich über
Offener Zugang
Dauer
00:05:38 Min
Aufnahmedatum
2020-08-25
Hochgeladen am
2020-10-16 18:46:31
Sprache
de-DE
Zeitgesteuertes Warten für Aufgabe 6 der Lehrveranstaltung Betriebssysteme.
Folien und Transkript zum Video.